﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sunny.UI;
using NovoSerDes;
using NovoDataBase;
using NovoUI;
using NovoUI.UserCtrl;
using Sunny.UI.Win32;
using System.Xml.Linq;
using System.Runtime.InteropServices;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.IO;

namespace NovoSerDes.Forms
{
    public partial class Form_EFUSE : UIForm
    {
        SerDesComm commDev;
        OutputLogCtrl logWin = new OutputLogCtrl();
        int efuseAddr = 0x0;
        private uint[] EfuseAddressMapData = new uint[16];
        private char[,] EfuseAddressMapBitData = new char[16, 32];
        string[] msg = new string[16];
        string csvFilePath = "";

        public Form_EFUSE(SerDesComm _commDev)
        {
            InitializeComponent();
            commDev = _commDev;
            this.panel_EfuseLog.Controls.Add(logWin);
            logWin.Dock = DockStyle.Fill;
            EfuseAddressMapInit();
            uiCheckBox_EFUSEReadOnly.Checked = true;
        }

        private IICMode IICModeDecode(string msg)
        {
            IICMode i2cMode = IICMode.A16D32;
            if (Enum.TryParse(msg.ToUpper(), true, out i2cMode))
                return i2cMode;
            else
                return IICMode.None;
        }

        private void PrintInfo(string msg)
        {
            logWin.AppendLog(msg);
        }

        private bool IICWr(byte _chipAddr, object regAddr, object regData, IICMode _iicMode, int byteCnt_RegAddr, int byteCnt_RegData)
        {
            bool ret = commDev.IICWrite(_chipAddr, regAddr, regData, _iicMode);
            if (ret)
            {
                //PrintInfo(String.Format("IIC Write, Reg:0x{0} = 0x{1}\r\n",
                //    (Convert.ToUInt32(regAddr)).ToString(String.Format("X{0}", 2 * byteCnt_RegAddr)),
                //    (Convert.ToUInt32(regData)).ToString(String.Format("X{0}", 2 * byteCnt_RegData))));
            }
            else
                //MessageBox.Show("Efuse Write Failed!"); //现在失败会弹出多个提示框，有待优化？
                ShowErrorNotifier("Efuse Write Failed!");

            return ret;
        }

        private void IICRd(byte _chipAddr, object regAddr, object rdData, IICMode _iicMode, int byteCnt_RegAddr, int byteCnt_RegData)
        {
            rdData = 4294967295;
            bool ret = commDev.IICRead(_chipAddr, (object)regAddr, out rdData, _iicMode);
            if (ret)
            {
                this.numericUpDown_EfuseData.Value = Convert.ToDecimal(rdData);
                PrintInfo(String.Format("IIC Read, Reg:0x{0} = 0x{1}\r\n",
                    (Convert.ToUInt32(regAddr)).ToString(String.Format("X{0}", 2 * byteCnt_RegAddr)),
                    (Convert.ToUInt32(rdData)).ToString(String.Format("X{0}", 2 * byteCnt_RegData))));
            }
            else
                MessageBox.Show("Efuse Read Failed!");
        }

        private bool IICWrNoprint(byte _chipAddr, object regAddr, object regData, IICMode _iicMode, int byteCnt_RegAddr, int byteCnt_RegData)
        {
            bool ret = commDev.IICWrite(_chipAddr, regAddr, regData, _iicMode);
            if (!ret)
            {
                //MessageBox.Show("Efuse Write Failed!");
                ShowErrorNotifier("Efuse Write Failed!");
            }
            return ret;
        }

        private bool IICRdNoprint(byte _chipAddr, object regAddr, object rdData, IICMode _iicMode, int byteCnt_RegAddr, int byteCnt_RegData)
        {
            rdData = 4294967295;
            bool ret = commDev.IICRead(_chipAddr, (object)regAddr, out rdData, _iicMode);
            if (ret)
            {
                this.numericUpDown_EfuseData.Value = Convert.ToDecimal(rdData);
            }
            else
            {
                //MessageBox.Show("Efuse Read Failed!");
                ShowErrorNotifier("Efuse Read Failed!");
                ret = false;
            }
            return ret;
        }

        // 更新 efuseAddr
        private void UpdateefuseAddr(int InitEfuseAddr)
        {
            int bitAddr = (int)numericUpDown_EfuseBitAddr.Value;
            int regAddr = (int)numericUpDown_EfuseRegAddr.Value;
            bitAddr &= 0xF; // 保留低4位  
            regAddr &= 0x1F; // 保留低5位
            // 更新 efuseAddr 的低9位
            int newData = bitAddr | (regAddr << 4);
            // 将新数据写入 efuseAddr 的低9位
            efuseAddr = (InitEfuseAddr & ~0x1FF) | (newData & 0x1FF);
        }

        private void uiButton_EfusePreRead_Click(object sender, EventArgs e)
        {
            byte _chipAddr = (byte)(this.numericUpDown_ChipAddr.Value * 2); //I2C设备地址，左移1位是*2，因为要留低1位给读写位
            IICMode _iicMode = IICModeDecode("A16D32"); //0x24，表示RegAddress是16bit、RegData是32bit
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F; //0x02，然后*2，表示RegAddress是4个字节数
            int byteCnt_RegData = ((byte)_iicMode & 0x0F); //0x04，然后*2，表示RegData是8个字节数

            object rdData = 0;

            bool ret = true;
            //Efuse configure
            //STEP1 Efuse configure Pre Read
            ret = IICWrNoprint(_chipAddr, 0x1800, 0x4B00001, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写准备
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }

            ret = IICWrNoprint(_chipAddr, 0x1804, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            UpdateefuseAddr(0x30000);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            ret = IICRdNoprint(_chipAddr, 0x1814, rdData, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            UpdateefuseAddr(0x40000);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);

            if (!ret)
            {
                MessageBox.Show("Efuse PreRead Failed!");
                return;
            }

            uint efuseData = (uint)this.numericUpDown_EfuseData.Value;
            UpdateAddressMap(efuseData, (int)numericUpDown_EfuseBitAddr.Value);
            PrintInfo(String.Format(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"));
            PrintInfo(String.Format("写 A[3:0] = 0x{0}", ((int)numericUpDown_EfuseBitAddr.Value).ToString("X")));

            string efuseDataString = Convert.ToString(efuseData, 2).PadLeft(32, '0');
            string efuseDataSpaceString = "";
            for (int j = 0; j < efuseDataString.Length; j += 4)
            {
                efuseDataSpaceString += efuseDataString.Substring(j, 4) + " ";
            }
            PrintInfo(String.Format("预读取 A[8:4] Read Value bit stream：0b{0}", efuseDataSpaceString));
            PrintInfo(String.Format("————————————————————"));
        }

        private void uiButton_EFUSEWrite_Click(object sender, EventArgs e)
        {
            byte _chipAddr = (byte)(this.numericUpDown_ChipAddr.Value * 2); //I2C设备地址
            IICMode _iicMode = IICModeDecode("A16D32"); //0x24
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F; //0x02
            int byteCnt_RegData = ((byte)_iicMode & 0x0F); //0x04

            bool ret = true;

            //STEP2 Efuse configure Write
            UpdateefuseAddr(0x70000);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            UpdateefuseAddr(0x0);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            UpdateefuseAddr(0x70000);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse Write Failed!");
                return;
            }
            PrintInfo(String.Format("Write Address：A[3:0] = 0x{0}; A[8:4] = 0x{1}", ((int)numericUpDown_EfuseBitAddr.Value).ToString("X"), ((int)numericUpDown_EfuseRegAddr.Value).ToString("X")));
        }

        private void uiButton_EFUSEReadOnly_Click(object sender, EventArgs e)
        {
            byte _chipAddr = (byte)(this.numericUpDown_ChipAddr.Value * 2); //I2C设备地址
            IICMode _iicMode = IICModeDecode("A16D32"); //0x24
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F; //0x02
            int byteCnt_RegData = ((byte)_iicMode & 0x0F); //0x04

            object rdData = 0;

            bool ret = true;
            //STEP3 Efuse configure Read Only
            //UpdateefuseAddr(0x40000);
            //IICWr(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //可以注释掉;写控制信号，低9bit为efuse地址
            //IICWr(_chipAddr, 0x1808, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //可以注释掉

            ret = IICWrNoprint(_chipAddr, 0x1804, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            UpdateefuseAddr(0x30000);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            ret = IICRdNoprint(_chipAddr, 0x1814, rdData, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            UpdateefuseAddr(0x40000);
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);

            if (!ret)
            {
                MessageBox.Show("Efuse ReadOnly Failed!");
                return;
            }

            uint efuseData = (uint)this.numericUpDown_EfuseData.Value;
            UpdateAddressMap(efuseData, (int)numericUpDown_EfuseBitAddr.Value);

            PrintInfo(String.Format("Read Address：A[3:0] = 0x{0}", ((int)numericUpDown_EfuseBitAddr.Value).ToString("X")));
            PrintInfo(String.Format("A[8:4] Read Value：0x{0}", efuseData.ToString("X")));
            string efuseDataString = Convert.ToString(efuseData, 2).PadLeft(32, '0');
            string efuseDataSpaceString = "";
            for (int j = 0; j < efuseDataString.Length; j += 4)
            {
                efuseDataSpaceString += efuseDataString.Substring(j, 4) + " ";
            }
            PrintInfo(String.Format("A[8:4] Read Value bit stream：0b{0}", efuseDataSpaceString));
            PrintInfo(String.Format("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"));
        }

        private bool EfuseReadOne(int i)
        {
            byte _chipAddr = (byte)(this.numericUpDown_ChipAddr.Value * 2); //I2C设备地址
            IICMode _iicMode = IICModeDecode("A16D32"); //0x24
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F; //0x02
            int byteCnt_RegData = ((byte)_iicMode & 0x0F); //0x04

            object rdData = 0;

            int efuseAddr1 = 0x30000;
            efuseAddr1 += i;

            bool ret = true;

            ret = IICWrNoprint(_chipAddr, 0x1804, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr1, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICRdNoprint(_chipAddr, 0x1814, rdData, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            efuseAddr1 = 0x40000;
            efuseAddr1 += i;
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr1, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }

            return ret;
        }

        private void uiButton_EFUSEReadAll_Click(object sender, EventArgs e)
        {
            bool ret = true;
            //PrintInfo(String.Format("                  A[8:4]:\n"));
            for (int i = 15; i >= 0; i--)
            {
                ret = EfuseReadOne(i);
                if (!ret)
                {
                    MessageBox.Show("Efuse ReadAll Failed!");
                    return;
                }
                uint efuseData = (uint)this.numericUpDown_EfuseData.Value;
                EfuseAddressMapData[i] = efuseData;
                UpdateAddressMap(efuseData, i);
                PrintInfo(String.Format("Read Address：A[3:0] = 0x{0}", i.ToString("X")));
                PrintInfo(String.Format("A[8:4] Read Value：0x{0}", efuseData.ToString("X")));
                //PrintInfo(String.Format("A[{0}]:0x{1}", i.ToString("X"), efuseData.ToString("X")));
                string efuseDataString = Convert.ToString(efuseData, 2).PadLeft(32, '0');
                // 将二进制字符串转换为字符数组并存储到二维数组中  
                for (int j = 0; j < 32; j++)
                {
                    EfuseAddressMapBitData[i, j] = efuseDataString[j];
                }
                string efuseDataSpaceString = "";
                for (int j = 0; j < efuseDataString.Length; j += 4)
                {
                    efuseDataSpaceString += efuseDataString.Substring(j, 4) + " ";
                }
                PrintInfo(String.Format("A[8:4] Read Value bit stream：\n0b{0}\n", efuseDataSpaceString));
                //PrintInfo(String.Format("A[{0}]:\n0b{1}\n", i.ToString("X"), efuseDataSpaceString));
            }
            
        }

        private bool EfuseWriteOne(int i)
        {
            byte _chipAddr = (byte)(this.numericUpDown_ChipAddr.Value * 2); //I2C设备地址
            IICMode _iicMode = IICModeDecode("A16D32"); //0x24
            int byteCnt_RegAddr = ((byte)_iicMode >> 4) & 0x0F; //0x02
            int byteCnt_RegData = ((byte)_iicMode & 0x0F); //0x04

            int efuseAddr2 = 0x70000;
            efuseAddr2 += i;

            bool ret = true;

            ret = IICWrNoprint(_chipAddr, 0x1800, 0x4B00001, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写准备
            if (!ret)
            {
                return ret;
            }

            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr2, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            efuseAddr2 = 0x0;
            efuseAddr2 += i;
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr2, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1810, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            efuseAddr2 = 0x70000;
            efuseAddr2 += i;
            ret = IICWrNoprint(_chipAddr, 0x180C, efuseAddr2, _iicMode, byteCnt_RegAddr, byteCnt_RegData); //写控制信号，低9bit为efuse地址
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1808, 0x0, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }
            ret = IICWrNoprint(_chipAddr, 0x1804, 0x1, _iicMode, byteCnt_RegAddr, byteCnt_RegData);
            if (!ret)
            {
                return ret;
            }

            return ret;
        }

        private void uiSymbolButton_EFUSEWriteAll_Click(object sender, EventArgs e)
        {
            bool ret = true;
            DialogResult result = MessageBox.Show("确定要执行 EFUSE 烧写全部操作吗？", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {    
                for (int i = 0; i < 512; i++)
                {
                    ret = EfuseWriteOne(i);
                    if (!ret)
                    {
                        MessageBox.Show("Efuse WriteAll Failed!");
                        return;
                    }
                }
                PrintInfo("EFUSE Write All!!");
            }
            else
            {
                PrintInfo("Cancel EFUSE Write");
            }
        }

        List<UITextBox> efuseDataTextBoxs = new List<UITextBox>{};
        private void EfuseAddressMapInit()
        {
            for(int i = 0; i < 32; i++)
            {
                UILabel HighAddressLabel = new UILabel();
                HighAddressLabel.Text = String.Format("{0}", i.ToString("X"));
                HighAddressLabel.Name = "uiLabel_HighAddress" + i.ToString("D");
                HighAddressLabel.Size = new Size(29, 23);
                HighAddressLabel.Location = new Point(10 + (31 - i + 1) * (HighAddressLabel.Width), 3);
                panel_AddressMap.Controls.Add(HighAddressLabel);
            }
            for(int i = 0; i < 16; i++)
            {
                UILabel LowAddressLabel = new UILabel();
                LowAddressLabel.Text = String.Format("{0}", i.ToString("X"));
                LowAddressLabel.Name = "uiLabel_LowAddress" + i.ToString("D");
                LowAddressLabel.Size = new Size(29, 29);
                LowAddressLabel.Location = new Point(3, (15 - i + 1) * (LowAddressLabel.Height));
                panel_AddressMap.Controls.Add(LowAddressLabel);
                for (int j = 0; j < 32; j++)
                {
                    UITextBox efuseDataTextBox = new UITextBox();
                    efuseDataTextBox.Text = String.Format("0");
                    efuseDataTextBox.Name = "uiTextBox_efuseData" + ((i + 1) * (j + 1)).ToString("D"); //1~512
                    efuseDataTextBox.Size = new Size(29, 29);
                    efuseDataTextBox.TextAlignment = ContentAlignment.MiddleCenter;
                    efuseDataTextBox.Radius = 0;
                    efuseDataTextBox.Location = new Point(3 + LowAddressLabel.Width + 3 + (31 - j) * 29, LowAddressLabel.Top);
                    panel_AddressMap.Controls.Add(efuseDataTextBox);
                    efuseDataTextBoxs.Add(efuseDataTextBox);
                }
            }          
        }

        private void UpdateAddressMap(uint efuseData, int i) //按行来更新
        {
            for (int j = 0; j < 32; j++)
            {
                bool bitIsSet = ((efuseData >> j) & 1) == 1;
                efuseDataTextBoxs[32 * i + j].Text = bitIsSet ? "1" : "0";
                if(efuseDataTextBoxs[32 * i + j].Text == "1")
                {
                    efuseDataTextBoxs[32 * i + j].FillColor = Color.Red;
                }
                else
                {
                    efuseDataTextBoxs[32 * i + j].FillColor = Color.LawnGreen;
                }
                
            }
        }

        private void uiButton_ClearLog_Click(object sender, EventArgs e)
        {
            logWin.Clear();
        }

        private void uiButton_EFUSEWrite5A_Click(object sender, EventArgs e)
        {
            bool ret = true;
            DialogResult result = MessageBox.Show("确定要执行 EFUSE 烧写5A操作吗？", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {
                PrintInfo("EFUSE Write 5A!!"); 
                for (int column = 0; column < 32; column++)
                {
                    int startIndex = column * 16;

                    for (int row = (column % 2 == 0) ? 0 : 1; row < 16; row += 2)
                    {
                        int index = startIndex + row;
                        if (index == 0 || index == 16 || index == 32 || index == 48)
                        {
                            continue;
                        }
                        ret = EfuseWriteOne(index);
                        if (!ret)
                        {
                            MessageBox.Show("Efuse Write5A Failed!");
                            return;
                        }
                        Console.WriteLine($"Writing EFUSE at index: {index}");
                    }
                }
            }
            else
            {
                PrintInfo("Cancel EFUSE Write");
            }
        }

        private void uiButton_EFUSEWriteA5_Click(object sender, EventArgs e)
        {
            bool ret = true;
            DialogResult result = MessageBox.Show("确定要执行 EFUSE 烧写A5操作吗？", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {
                PrintInfo("EFUSE Write A5!!");
                for (int column = 0; column < 32; column++)
                {
                    int startIndex = column * 16;

                    for (int row = (column % 2 == 0) ? 1 : 0; row < 16; row += 2)
                    {
                        int index = startIndex + row;
                        if (index == 0 || index == 16 || index == 32 || index == 48)
                        {
                            continue;
                        }
                        ret = EfuseWriteOne(index);
                        if (!ret)
                        {
                            MessageBox.Show("Efuse WriteA5 Failed!");
                            return;
                        }
                        Console.WriteLine($"Writing EFUSE at index: {index}");
                    }
                }
            }
            else
            {
                PrintInfo("Cancel EFUSE Write");
            }
        }

        private void uiButton_EFUSEWriteFF_Click(object sender, EventArgs e)
        {
            bool ret = true;
            DialogResult result = MessageBox.Show("确定要执行 EFUSE 烧写FF操作吗？", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {
                PrintInfo("EFUSE Write FF!!");
                for (int i = 1; i < 512; i++)
                {
                    if (i == 0 || i == 16 || i == 32 || i == 48)
                    {
                        continue;
                    }
                    ret = EfuseWriteOne(i);
                    if (!ret)
                    {
                        MessageBox.Show("Efuse WriteFF Failed!");
                        return;
                    }
                    Console.WriteLine($"Writing EFUSE at index: {i}");
                }
            }
            else
            {
                PrintInfo("Cancel EFUSE Write");
            }
        }

        private void uiButton_EFUSEWriteID_Click(object sender, EventArgs e)
        {
            bool ret = true;
            DialogResult result = MessageBox.Show("确定要执行 EFUSE 烧写ID操作吗？", "确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {
                PrintInfo("EFUSE Write ID!!");
                int efuseId = (int)numericUpDown_EFUSEWriteID.Value;
                for (int bitPosition = 0; bitPosition < 4; bitPosition++)
                {
                    int mask = 1 << bitPosition;

                    if ((efuseId & mask) != 0)
                    {
                        int i = bitPosition * 16;
                        ret = EfuseWriteOne(i);
                        if (!ret)
                        {
                            MessageBox.Show("Efuse WriteID Failed!");
                            return;
                        }
                        Console.WriteLine($"Writing EFUSE at index: {i}");
                    }
                }
            }
            else
            {
                PrintInfo("Cancel EFUSE Write");
            }
        }

        private void uiButton_EFUSECheck5A_Click(object sender, EventArgs e)
        {
            bool isCorrectPattern = true;
            List<int> incorrectAddresses = new List<int>();
            bool ret = true;

            for (int i = 15; i >= 0; i--)
            {
                ret = EfuseReadOne(i);
                if (!ret)
                {
                    MessageBox.Show("Efuse Check5A Failed!");
                    return;
                }
                uint efuseData = (uint)this.numericUpDown_EfuseData.Value;

                uint expectedValue = (i % 2 == 0 && i != 0) ? 0x55555555u : (i == 0 ? 0x55555550u : 0xAAAAAAAAu);

                // 检查efuseData是否符合5A模式  
                if (((i % 2 == 0 && i != 0) && efuseData != 0x55555555) || // 偶数索引应该是0x55555555
                    (i % 2 != 0 && efuseData != 0xAAAAAAAA) || // 奇数索引应该是0xAAAAAAAA
                    (i == 0 && (efuseData & 0xFFFFFFF0) != 0x55555550)) // i为0时，忽略最后4位，只比较前28位    
                {
                    isCorrectPattern = false; // 如果不符合，则设置标志为false  
                    incorrectAddresses.Add(i); // 将不符合的地址添加到列表中 
                    //PrintInfo(String.Format("— — — — — — — — — — — — — — — — —"));
                    //PrintInfo(String.Format("Wrong!!  Read Address：A[3:0] = 0x{0} is Not 5A Pattern", i.ToString("X")));
                    //PrintInfo(String.Format("Wrong!!  A[8:4] Read Value：0x{0}", efuseData.ToString("X")));
                    //PrintInfo("");

                    // 找出不符合的位  
                    //for (int bitIndex = 0; bitIndex < 32; bitIndex++)
                    //{
                    //    uint mask = 1u << bitIndex;
                    //    bool expectedBit = (expectedValue & mask) != 0;
                    //    bool actualBit = (efuseData & mask) != 0;

                    //    if (expectedBit != actualBit)
                    //    {
                    //        PrintInfo($"Wrong!! A[3:0] = 0x{i:X} 中的 A[8:4] Bit 0x{bitIndex:X} 不符");
                    //        PrintInfo("");
                    //    }
                    //}
                    //PrintInfo(String.Format("— — — — — — — — — — — — — — — — —"));
                }
            }

            // 根据检查结果输出信息  
            if (isCorrectPattern)
            {
                PrintInfo(String.Format("————————————————————"));
                PrintInfo("EFUSE Check 5A Pattern: Correct");
                UIMessageBox.ShowSuccess("EFUSE Check 5A Pattern: Correct!", true, true);
                PrintInfo(String.Format("————————————————————"));
            }
            else
            {
                PrintInfo(String.Format("————————————————————"));
                PrintInfo("EFUSE Check 5A Pattern: Incorrect");
                foreach (int addr in incorrectAddresses) // 遍历不符合的地址列表  
                {
                    PrintInfo(String.Format("Address:A[3:0] = 0x{0} Incorrect", addr.ToString("X")));
                }
                PrintInfo(String.Format("————————————————————"));
                UIMessageBox.ShowError("EFUSE Check 5A Pattern: Incorrect!", true, true);
            }
        }

        private void uiButton_EFUSECheckA5_Click(object sender, EventArgs e)
        {
            bool isCorrectPattern = true;
            List<int> incorrectAddresses = new List<int>();
            bool ret = true;

            for (int i = 15; i >= 0; i--)
            {
                ret = EfuseReadOne(i);
                if (!ret)
                {
                    MessageBox.Show("Efuse CheckA5 Failed!");
                    return;
                }
                uint efuseData = (uint)this.numericUpDown_EfuseData.Value;

                uint expectedValue = (i % 2 == 0 && i != 0) ? 0xAAAAAAAAu : (i == 0 ? 0xAAAAAAA0u : 0x55555555u);

                // 检查efuseData是否符合A5模式  
                if (((i % 2 == 0 && i != 0) && efuseData != 0xAAAAAAAA) || // 偶数索引应该是0xAAAAAAAA
                    (i % 2 != 0 && efuseData != 0x55555555) || // 奇数索引应该是0x55555555
                    (i == 0 && (efuseData & 0xFFFFFFF0) != 0xAAAAAAA0)) // i为0时，忽略最后4位，只比较前28位    
                {
                    isCorrectPattern = false; // 如果不符合，则设置标志为false  
                    incorrectAddresses.Add(i); // 将不符合的地址添加到列表中 
                    //PrintInfo(String.Format("— — — — — — — — — — — — — — — — —"));
                    //PrintInfo(String.Format("Wrong!!  Read Address：A[3:0] = 0x{0} is Not A5 Pattern", i.ToString("X")));
                    //PrintInfo(String.Format("Wrong!!  A[8:4] Read Value：0x{0}", efuseData.ToString("X")));
                    //PrintInfo("");

                    // 找出不符合的位  
                    //for (int bitIndex = 0; bitIndex < 32; bitIndex++)
                    //{
                    //    uint mask = 1u << bitIndex;
                    //    bool expectedBit = (expectedValue & mask) != 0;
                    //    bool actualBit = (efuseData & mask) != 0;

                    //    if (expectedBit != actualBit)
                    //    {
                    //        PrintInfo($"Wrong!! A[3:0] = 0x{i:X} 中的 A[8:4] Bit 0x{bitIndex:X} 不符");
                    //        PrintInfo("");
                    //    }
                    //}
                    //PrintInfo(String.Format("— — — — — — — — — — — — — — — — —"));
                }
            }

            // 根据检查结果输出信息  
            if (isCorrectPattern)
            {
                PrintInfo(String.Format("————————————————————"));
                PrintInfo("EFUSE Check A5 Pattern: Correct");
                UIMessageBox.ShowSuccess("EFUSE Check A5 Pattern: Correct!", true, true);
                PrintInfo(String.Format("————————————————————"));
            }
            else
            {
                PrintInfo(String.Format("————————————————————"));
                PrintInfo("EFUSE Check A5 Pattern: Incorrect");
                foreach (int addr in incorrectAddresses) // 遍历不符合的地址列表  
                {
                    PrintInfo(String.Format("Address:A[3:0] = 0x{0} Incorrect", addr.ToString("X")));
                }
                PrintInfo(String.Format("————————————————————"));
                UIMessageBox.ShowError("EFUSE Check A5 Pattern: Incorrect!", true, true);
            }
        }

        private void uiButton_EFUSECheckFF_Click(object sender, EventArgs e)
        {
            bool isCorrectPattern = true;
            List<int> incorrectAddresses = new List<int>();
            bool ret = true;

            for (int i = 15; i >= 0; i--)
            {
                ret = EfuseReadOne(i);
                if (!ret)
                {
                    MessageBox.Show("Efuse CheckFF Failed!");
                    return;
                }
                uint efuseData = (uint)this.numericUpDown_EfuseData.Value;

                uint expectedValue = (i % 2 == 0 && i != 0) ? 0xFFFFFFFFu : (i == 0 ? 0xFFFFFFF0u : 0xFFFFFFFFu);

                // 检查efuseData是否符合FF模式  
                if (((i % 2 == 0 && i != 0) && efuseData != 0xFFFFFFFF) || // 偶数索引应该是0xFFFFFFFF
                    (i % 2 != 0 && efuseData != 0xFFFFFFFF) || // 奇数索引应该是0xFFFFFFFF
                    (i == 0 && (efuseData & 0xFFFFFFF0) != 0xFFFFFFF0)) // i为0时，忽略最后4位，只比较前28位    
                {
                    isCorrectPattern = false; // 如果不符合，则设置标志为false  
                    incorrectAddresses.Add(i); // 将不符合的地址添加到列表中 
                    //PrintInfo(String.Format("— — — — — — — — — — — — — — — — —"));
                    //PrintInfo(String.Format("Wrong!!  Read Address：A[3:0] = 0x{0} is Not FF Pattern", i.ToString("X")));
                    //PrintInfo(String.Format("Wrong!!  A[8:4] Read Value：0x{0}", efuseData.ToString("X")));
                    //PrintInfo("");

                    // 找出不符合的位  
                    //for (int bitIndex = 0; bitIndex < 32; bitIndex++)
                    //{
                    //    uint mask = 1u << bitIndex;
                    //    bool expectedBit = (expectedValue & mask) != 0;
                    //    bool actualBit = (efuseData & mask) != 0;

                    //    if (expectedBit != actualBit)
                    //    {
                    //        PrintInfo($"Wrong!! A[3:0] = 0x{i:X} 中的 A[8:4] Bit 0x{bitIndex:X} 不符");
                    //        PrintInfo("");
                    //    }
                    //}
                    //PrintInfo(String.Format("— — — — — — — — — — — — — — — — —"));
                }
            }

            // 根据检查结果输出信息  
            if (isCorrectPattern)
            {
                PrintInfo(String.Format("————————————————————"));
                PrintInfo("EFUSE Check FF Pattern: Correct");
                UIMessageBox.ShowSuccess("EFUSE Check FF Pattern: Correct!", true, true);
                PrintInfo(String.Format("————————————————————"));
            }
            else
            {
                PrintInfo(String.Format("————————————————————"));
                PrintInfo("EFUSE Check FF Pattern: Incorrect");
                foreach (int addr in incorrectAddresses) // 遍历不符合的地址列表  
                {
                    PrintInfo(String.Format("Address:A[3:0] = 0x{0} Incorrect", addr.ToString("X")));
                }
                PrintInfo(String.Format("————————————————————"));
                UIMessageBox.ShowError("EFUSE Check FF Pattern: Incorrect!", true, true);
            }
        }

        private void uiCheckBox_EFUSEReadOnly_CheckedChanged(object sender, EventArgs e)
        {
            if (uiCheckBox_EFUSEReadOnly.Checked)
            {
                uiButton_EFUSEWrite.Enabled = false;
                uiSymbolButton_EFUSEWriteAll.Enabled = false;
                uiButton_EFUSEWrite5A.Enabled = false;
                uiButton_EFUSEWriteA5.Enabled = false;
                uiButton_EFUSEWriteFF.Enabled = false;
                uiButton_EFUSEWriteID.Enabled = false;
            }
            else
            {
                uiButton_EFUSEWrite.Enabled = true;
                uiSymbolButton_EFUSEWriteAll.Enabled = true;
                uiButton_EFUSEWrite5A.Enabled = true;
                uiButton_EFUSEWriteA5.Enabled = true;
                uiButton_EFUSEWriteFF.Enabled = true;
                uiButton_EFUSEWriteID.Enabled = true;
            }
        }

        //捕获当前Form的截图并将其保存为图片文件
        private void uiButton_DumpAddressMap_Click(object sender, EventArgs e)
        {
            DumpAddressMapToCsv();
            SaveAddressMapToPng();
        }

        private void DumpAddressMapToCsv()
        {
            SaveFileDialog savefiledlg = new SaveFileDialog();
            savefiledlg.Title = "Dump to...";
            savefiledlg.Filter = "CSV file(*.csv)|*.csv";
            savefiledlg.RestoreDirectory = true;
            string filename = "";
            if (savefiledlg.ShowDialog() == DialogResult.OK)
            {
                filename = savefiledlg.FileName;
                csvFilePath = savefiledlg.FileName;
            }
            else
                return;

            try
            {
                using (StreamWriter writer = new StreamWriter(filename))
                {
                    writer.WriteLine(string.Join(",", new string[] { "A[3:0](H)", "efuseData","A[8:4](H):",
                        "1F", "1E", "1D", "1C", "1B", "1A", "19", "18", "17", "16", "15", "14", "13", "12", "11", "10",
                        "F", "E", "D", "C", "B", "A", "9", "8", "7", "6", "5", "4", "3", "2", "1", "0"
                    }));
                    for (int i = 15; i >= 0; i--)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append(i.ToString("X"));
                        sb.Append(",0x");
                        sb.Append(EfuseAddressMapData[i].ToString("X8"));
                        sb.Append(", ,");

                        for (int j = 0; j < 32; j++)
                        {
                            sb.Append(EfuseAddressMapBitData[i, j]);
                            if (j < 31) // 不是最后一位，添加逗号  
                            {
                                sb.Append(",");
                            }
                        }
                        msg[i] = sb.ToString();
                        writer.WriteLine(msg[i]);
                    } 
                }
                Console.WriteLine($"Dump AddressMap To CSV Suceess");
                MessageBox.Show("Save AddressMap To CSV Suceess");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Dump AddressMap To CSV Fail: {ex.Message}");
            }
        }

        private void SaveAddressMapToPng()
        {
            // 创建一个与Form大小相同的Bitmap对象  
            Bitmap bitmap = new Bitmap(this.Width, this.Height);

            // 创建一个Graphics对象，用于绘制Form到Bitmap  
            Graphics g = Graphics.FromImage(bitmap);

            // 清除背景色（可选，如果需要透明背景则跳过此步骤）  
            g.Clear(this.BackColor);

            // 将Form绘制到Bitmap上  
            this.DrawToBitmap(bitmap, new Rectangle(0, 0, this.Width, this.Height));

            // 保存Bitmap为图片文件  
            string directory = Path.GetDirectoryName(csvFilePath); // 获取目录路径  
            string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(csvFilePath);// 提取文件名（不包括路径和扩展名） 
            string filePath = Path.Combine(directory, fileNameWithoutExtension + ".png");
            //string filePath = CreatePNGSavePath(); // 指定保存路径  
            if (filePath == null)
            {
                return;
            }
            bitmap.Save(filePath, System.Drawing.Imaging.ImageFormat.Png); // 使用PNG格式保存  

            // 释放Graphics和Bitmap资源  
            g.Dispose();
            bitmap.Dispose();

            // 提示截图已保存（可选）  
            MessageBox.Show("Save AddressMap To Png Suceess");
        }

        private string CreatePNGSavePath()
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Title = "Save PNG File...";
            saveFileDialog.Filter = "PNG Image (*.png)|*.png|JPEG Image (*.jpeg)|*.jpeg|Bitmap Image (*.bmp)|*.bmp";
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                string SaveCFilePath = saveFileDialog.FileName;
                return SaveCFilePath;
            }
            else
            {
                return null;
            }
        }
    }
}
